<?php

namespace plugin\thinkphp\form;


use ExAdmin\ui\contract\ValidatorAbstract;
use ExAdmin\ui\response\Response;
use ExAdmin\ui\support\Arr;
use think\facade\Validate;

class Validator extends ValidatorAbstract
{
    /**
     * 验证数组
     * @param $data
     * @param $field
     * @param $rule
     * @param $messages
     * @return bool
     */
    protected function arrValidate($data,$field,$rule,$messages){
        $path = rtrim(explode('*', $field)[0], '.');
        $data = Arr::get($data,$path,[]);
        $data = Arr::dot($data,$path.'.');
        $pattern = str_replace('\*', '[^\.]*', preg_quote($field));
        foreach ($data as $key=>$value){
            if ((bool) preg_match('/^'.$pattern.'\z/', $key)) {
                $paths = explode('.',$key);
                $validateField = end($paths);
                $message[] = [];
                foreach ($messages as $msg){
                    $message[$validateField] = $msg;
                }
                $valiData[$validateField] = $value;
                $validator = Validate::rule([$validateField=>$rule])->message($message);
                $validator->batch()->check($valiData);
                if ($validator->getError()) {
                    $errors = [];
                    foreach ($validator->getError() as $value){
                        $errors[$key][] = $value;
                    }
                    return Response::success($errors, '', 422);
                }
            }
        }
        return true;
    }
    /**
     * 验证
     * @param array $data 表单数据
     * @param bool $edit true更新，false新增
     * @return mixed
     */
    function check(array $data, bool $edit)
    {
        $ruleArr = $edit ? $this->updateRule : $this->createRule;
        $rules = [];
        $messages = [];
        foreach ($ruleArr as $field => $row) {
            $rule = [];
            if($row instanceof \Closure){
                $row = call_user_func_array($row,[$data,$this->form]);
            }
            foreach ($row as $key => $item) {
                if (is_numeric($key)) {
                    $rule[] = $item;
                } else {
                    $rule[] = $key;
                    $index = strpos($key, ':');
                    if ($index !== false) {
                        $key = substr($key, 0, $index);
                    }
                    $messages["{$field}.{$key}"] = $item;
                }
            }
            if(strpos($field,'*') !== false){
                $response = $this->arrValidate($data,$field,$rule,$messages);
                if($response instanceof Response){
                    return $response;
                }
            }
            $rules[$field] = $rule;
        }

        $validator = Validate::rule($rules)->message($messages);
        $validator->batch()->check($data);
        if ($validator->getError()) {
            return Response::success($validator->getError(), '', 422);
        }
        if($this->form->getSteps()){
            if(!$this->form->isStepfinish()){
                return Response::success([], '', 201);
            }
        }
        return true;
    }
}
